package sunyu.demo.spring.netty;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
import org.slf4j.Logger;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import sunyu.toolkit.core.LogKit;

import java.net.InetAddress;

/**
 * 具体的业务逻辑
 *
 * @author 孙宇
 */
@Service
@Scope("prototype")
@ChannelHandler.Sharable//@Sharable意义是，可以让他在channels间共享
public class TcpChannelInboundHandler extends SimpleChannelInboundHandler<String> {

    private static final Logger logger = LogKit.getLogger();

    private static ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    /**
     * 服务端读取到客户端信息
     *
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        logger.debug("客户端 {} 向 {} 发送数据 {}", ctx.channel().remoteAddress(), InetAddress.getLocalHost().getHostName(), msg);
    }

    /**
     * 服务端监听客户端活动
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        logger.debug("客户端 {} 活动", ctx.channel().remoteAddress());
        //channelHandlerContext.writeAndFlush(String.format("Welcome to %s service! \n", InetAddress.getLocalHost().getHostName()));
        super.channelActive(ctx);
    }

    /**
     * 服务端监听客户端掉线
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        logger.debug("客户端 {} 不活跃", ctx.channel().remoteAddress());
        super.channelInactive(ctx);
    }

    /**
     * 服务端接收到新客户端连接
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        logger.debug("客户端 {} 加入 {} 通道ID {}", channel.remoteAddress(), InetAddress.getLocalHost().getHostName(), channel.id());
        /*for (Channel c : channels) {
            c.writeAndFlush(String.format("[Server] - %s 加入\n", channel.remoteAddress()));
        }*/
        //super.handlerAdded(ctx);
        channels.add(channel);
    }

    /**
     * 服务端接收到客户端断开
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        logger.debug("客户端 {} 离开 {}", channel.remoteAddress(), InetAddress.getLocalHost().getHostName());
        /*for (Channel c : channels) {
            c.writeAndFlush(String.format("[Server] - %s 离开\n", channel.remoteAddress()));
        }*/
        //super.handlerRemoved(ctx);
        channels.remove(ctx.channel());
    }

    /**
     * 出现异常
     *
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
    }

}
